#include "mtwidget.h"

MTWidget::MTWidget( const QPixmap & pixmap, QGraphicsItem * parent ):
        QGraphicsPixmapItem(pixmap,parent){
this->acceptHoverEvents();}

qreal sqr (qreal a){
    return a*a;
}
qreal pointDistance(QPointF a, QPointF b){
    return sqrt((sqr(a.x() - b.x()) + sqr(a.y() - b.y())));
}
QPointF* intersection(QLineF r, QLineF s){
    QPointF* intersect = new QPointF(0,0);
    if (r.angle() != s.angle()){
        /*r: y = ax + b
          s: y = cx + d
          intersect.x = d-b/a-c
        */
        qreal a = !(r.x2() - r.x1() ==0)?  r.y2()-r.y1()/ r.x2() - r.x1() : 0;
        qreal c = !(s.x2() - s.x1() ==0)?  s.y2()-s.y1()/ s.x2() - s.x1() : 0;
        qreal b = r.y1() - a*r.x1();
        qreal d = s.y1() - c*s.x1();
        intersect->setX(d-b/a-c);
        intersect->setY(a*intersect->x() + b);
    }
    return intersect;
}

int MTWidget::findSecondTouch(int touchID)
{
        QMapIterator<int, QPointF> i(this->touches);
        while (i.hasNext()) {
            i.next();
            int tID = i.key();
            QPointF p;
            if (this->touches.contains(tID)){
                p = touches.value(tID);
                if(this->contains(p) and tID!= touchID)
                    return tID;
            }
        }
        return -1;
}

void MTWidget::rotateZoomMove(int touchID, QPointF pos){

        // some default values, in case we dont calculate them,
        qreal rotation = 0;
        qreal scale = 1;
        QPointF trans = QPointF(0,0);
        QPointF* intersect = new QPointF(0,0);
        // we definitly have one point
        //p1_start é onde o ponto estava antes de se mover.
        //p1_now é para onde o ponto se moveu.
        QPointF p1_start = this->touches.value(touchID);
        QPointF p1_now   = pos;
        QPointF rotationPoint = QPointF(0,0);
        // if we have a second point, do the scale/rotate thing
        int second_touch = this->findSecondTouch(touchID);
        if (second_touch!= -1){
            //p2 é um outro ponto, no caso o fixo, por isso sao iguais
            QPointF p2_start = this->touches.value(second_touch);
            QPointF p2_now   = this->touches.value(second_touch);
            // compute scale factor
            qreal old_dist = pointDistance(p1_start, p2_start);
            qreal new_dist = pointDistance(p1_now ,p2_now);
            scale = new_dist/old_dist;
            this->scale(scale,scale);

            // find intersection between lines...the point around which to rotate
            const QLineF a = QLineF(p1_start, p2_start);
            const QLineF b = QLineF(p1_now, p2_now);
            a.intersect(b,intersect);

            // compute rotation angle
            QLineF old_line = QLineF(QPoint(), p1_start - p2_start);
            QLineF new_line = QLineF(QPoint(), p1_now - p2_now);
            rotation = -1.0 * old_line.angleTo(new_line);
            qDebug() << rotation;
            qreal x = (p1_start.x());
            qreal y = (p1_start.y());
            //this->setPos(this->pos() + p1_start);
            //this->translate(x,y);
            this->rotate(rotation);
            //this->setPos(this->pos() - p1_start);
            //this->translate(-x,-y);

        }
        else {
            trans = p1_now - p1_start;
            this->setPos(this->pos()+trans);
        }

        QRectF r = this->sceneBoundingRect();
        double w = r.width();
        double h = r.height();
        qreal x = rotationPoint.x();
        qreal y = rotationPoint.y();
        //this->setTransform(QTransform().translate(x, y).rotate(rotation).translate(-x, -y));
        // save new position of the current touch
        this->touches[touchID] = pos;
}

bool MTWidget::onTouchDown(int touchId, QPointF pos){
    if(this->touches.contains(touchId))
        return false;

    this->touches[touchId] = pos;
    return true;

    }

bool MTWidget::onTouchUp(int touchId, QPointF pos){
    if(!this->touches.contains(touchId))
        return false;
    this->touches.remove(touchId);
    return true;
}

bool MTWidget::onTouchMove(int touchId, QPointF pos){
    //Se nao foi clicado em mim, ou nao ta em minha lista
    if(!(this->contains(pos)or this->touches.count(touchId)>0))
            return false;
    // Se for um toque ja registrado
    if (this->touches.count(touchId)>0){
        this->rotateZoomMove(touchId, pos);
        return true;
    }
    return this->touches.contains(touchId);
}

void MTWidget::onTouch(int touchId, double x, double y, int type){

    switch (type){
        case TOUCHDOWN:
            this->onTouchDown(touchId, QPointF(x,y));
            break;
        case TOUCHUP:
            this->onTouchUp(touchId, QPointF(x,y));
            break;
        case TOUCHMOVE:
            this->onTouchMove(touchId, QPointF(x,y));
            break;
        }
}

void MTWidget::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
    this->onTouch(1, event->pos().x(),event->pos().y(),TouchType(TOUCHMOVE));
}






















MTWidget::~MTWidget()
{

}
